/*           Copyright(c) 2005-2008 Dave Sexton            *
 *                   HtmlEditor Control                    *
 * http://www.codeplex.com/DocProject/Project/License.aspx *
 ***********************************************************/
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.ComponentModel;
using mshtml;

namespace DaveSexton.Controls
{
	[DefaultProperty("Editor"), Editor(typeof(Design.HtmlEditorSelectorEditor), typeof(System.Drawing.Design.UITypeEditor))]
	public partial class HtmlEditorToolStrip : ToolStrip
	{
		#region Public Properties
		[Category("Sections"), DefaultValue(true), Description("")]
		public bool FontSizeSelectorVisible
		{
			get
			{
				return lstFontSizesVisible;
			}
			set
			{
				lstFontSizesVisible = value;
				lstFontSizes.Visible = value;
			}
		}

		[Category("Sections"), DefaultValue(true), Description("")]
		public bool FontStylesVisible
		{
			get
			{
				return fontStylesVisible;
			}
			set
			{
				fontStylesVisible = value;
				
				fontStylesSeparator.Visible = value;
				btnBold.Visible = value;
				btnItalic.Visible = value;
				btnUnderline.Visible = value;
			}
		}

		[Category("Sections"), DefaultValue(true), Description("")]
		public bool TextAlignmentVisible
		{
			get
			{
				return textAlignmentVisible;
			}
			set
			{
				textAlignmentVisible = value;

				textAlignmentSeparator.Visible = value;
				btnJustifyLeft.Visible = value;
				btnJustifyCenter.Visible = value;
				btnJustifyRight.Visible = value;
			}
		}

		[Category("Sections"), DefaultValue(true), Description("")]
		public bool ColumnAlignmentVisible
		{
			get
			{
				return columnAlignmentVisible;
			}
			set
			{
				columnAlignmentVisible = value;

				columnAlignmentSeparator.Visible = value;
				btnIndent.Visible = value;
				btnOutdent.Visible = value;
			}
		}

		[Category("Sections"), DefaultValue(true), Description("")]
		public bool TagGlyphControlVisible
		{
			get
			{
				return btnToggleTagGlyphsVisible;
			}
			set
			{
				btnToggleTagGlyphsVisible = value;

				tagGlyphControlSeparator.Visible = value;
				btnToggleTagGlyphs.Visible = value;
			}
		}

		[Category("Misc"), DefaultValue(null), Description("")]
		public HtmlEditor Editor
		{
			get
			{
				return editor;
			}
			set
			{
				if (editor != null)
					UnbindEditorEvents();

				editor = value;

				if (editor != null)
					BindEditorEvents();
			}
		}
		#endregion

		#region Private / Protected
		private HtmlEditor editor;
		private bool suspendFontSizeChange;
		private bool btnToggleTagGlyphsVisible = true, columnAlignmentVisible = true;
		private bool textAlignmentVisible = true, fontStylesVisible = true, lstFontSizesVisible = true;
		#endregion

		#region Constructors
		/// <summary>
		/// Constructs a new instance of the <see cref="HtmlEditorToolStrip" /> class.
		/// </summary>
		public HtmlEditorToolStrip()
		{
			InitializeComponent();
		}
		#endregion

		#region Methods
		private void BindEditorEvents()
		{
			editor.SelectionChanged += new EventHandler<HtmlEditorEventArgs>(editor_SelectionChanged);

			btnInsertImage.Visible = editor.CanInsertPicture;
		}

		private void UnbindEditorEvents()
		{
			editor.SelectionChanged -= new EventHandler<HtmlEditorEventArgs>(editor_SelectionChanged);
		}

		private void UpdateToolbar()
		{
			if (editor.Document.ActiveElement != null && HtmlSelection.IsEditableElement(editor.Document.ActiveElement).GetValueOrDefault(true))
			{
				UpdateFontSizes();

				UpdateFontStyles();

				UpdateJustificationCommands();

				btnIndent.Enabled = editor.Commands.Indent.Supported && editor.Commands.Indent.Enabled;
				btnOutdent.Enabled = editor.Commands.Outdent.Supported && editor.Commands.Outdent.Enabled;

				IHTMLElement control = editor.SelectedControl;
				IHTMLAnchorElement anchor = control as IHTMLAnchorElement;
				IHTMLImgElement image = control as IHTMLImgElement;

				if (editor.CanInsertPicture)
					btnInsertImage.Enabled = image == null && editor.Commands.InsertImage.Supported && editor.Commands.InsertImage.Enabled;

				btnInsertHyperlink.Enabled = anchor == null && editor.Commands.CreateLink.Supported && editor.Commands.CreateLink.Enabled;
			}
			else
			{
				suspendFontSizeChange = true;
				lstFontSizes.Enabled = false;
				lstFontSizes.SelectedIndex = 2;
				suspendFontSizeChange = false;

				btnIndent.Enabled = false;
				btnOutdent.Enabled = false;
				btnInsertImage.Enabled = false;
				btnInsertHyperlink.Enabled = false;
				btnBold.Enabled = btnBold.Checked = false;
				btnItalic.Enabled = btnItalic.Checked = false;
				btnUnderline.Enabled = btnUnderline.Checked = false;
				btnJustifyLeft.Enabled = btnJustifyLeft.Checked = false;
				btnJustifyRight.Enabled = btnJustifyRight.Checked = false;
				btnJustifyCenter.Enabled = btnJustifyCenter.Checked = false;
			}
		}

		private void UpdateFontSizes()
		{
			int index = editor.SelectedHtmlFontSize - 1;

			// When multiple objects or elements are selected, the current index might only specify a portion
			// of the font sizes of the selected text range.  Therefore, when updating lstFontSizes the code should
			// not attempt to set the current font size.  (Doing so will cause the font size of selected text to change
			// when it's double clicked.  This occurs because double-clicking causes the trailing spaces up until the next word 
			// to be selected and it's possible that all or some of the trailing spaces are contained by an element with
			// a different font size.
			suspendFontSizeChange = true;

			lstFontSizes.Enabled = true;

			if (lstFontSizes.SelectedIndex != index)
				lstFontSizes.SelectedIndex = index;

			suspendFontSizeChange = false;
		}

		private void UpdateFontStyles()
		{
			if (true == (btnBold.Enabled = editor.Commands.Bold.Supported && editor.Commands.Bold.Enabled))
				btnBold.Checked = editor.Commands.Bold.GetValue(false);
			else
				btnBold.Checked = false;

			if (true == (btnItalic.Enabled = editor.Commands.Italic.Supported && editor.Commands.Italic.Enabled))
				btnItalic.Checked = editor.Commands.Italic.GetValue(false);
			else
				btnItalic.Checked = false;

			if (true == (btnUnderline.Enabled = editor.Commands.Underline.Supported && editor.Commands.Underline.Enabled))
				btnUnderline.Checked = editor.Commands.Underline.GetValue(false);
			else
				btnUnderline.Checked = false;
		}

		private void UpdateJustificationCommands()
		{
			if (true == (btnJustifyLeft.Enabled = editor.Commands.JustifyLeft.Supported && editor.Commands.JustifyLeft.Enabled))
				btnJustifyLeft.Checked = editor.Commands.JustifyLeft.GetValue(false);
			else
				btnJustifyLeft.Checked = false;

			if (true == (btnJustifyCenter.Enabled = editor.Commands.JustifyCenter.Supported && editor.Commands.JustifyCenter.Enabled))
				btnJustifyCenter.Checked = editor.Commands.JustifyCenter.GetValue(false);
			else
				btnJustifyCenter.Checked = false;

			if (true == (btnJustifyRight.Enabled = editor.Commands.JustifyRight.Supported && editor.Commands.JustifyRight.Enabled))
				btnJustifyRight.Checked = editor.Commands.JustifyRight.GetValue(false);
			else
				btnJustifyRight.Checked = false;
		}
		#endregion

		#region Event Handlers
		private void editor_SelectionChanged(object sender, DaveSexton.Controls.HtmlEditorEventArgs e)
		{
			UpdateToolbar();
		}

		private void lstFontSizes_SelectedIndexChanged(object sender, EventArgs e)
		{
			if (!suspendFontSizeChange)
				editor.SelectedHtmlFontSize = lstFontSizes.SelectedIndex + 1;
		}

		private void btnBold_Click(object sender, EventArgs e)
		{
			editor.Commands.Bold.Execute();
		}

		private void btnItalic_Click(object sender, EventArgs e)
		{
			editor.Commands.Italic.Execute();
		}

		private void btnUnderline_Click(object sender, EventArgs e)
		{
			editor.Commands.Underline.Execute();
		}

		private void btnIndent_Click(object sender, EventArgs e)
		{
			editor.Commands.Indent.Execute();
		}

		private void btnOutdent_Click(object sender, EventArgs e)
		{
			editor.Commands.Outdent.Execute();
		}

		private void btnInsertImage_Click(object sender, EventArgs e)
		{
			editor.Commands.InsertImage.Execute(true);
		}

		private void btnInsertHyperlink_Click(object sender, EventArgs e)
		{
			editor.Commands.CreateLink.Execute(true);
		}

		private void btnJustifyRight_Click(object sender, EventArgs e)
		{
			if (btnJustifyRight.Checked)
				editor.Commands.JustifyRight.Execute();
			else
				editor.Commands.JustifyNone.Execute();

			UpdateJustificationCommands();
		}

		private void btnJustifyCenter_Click(object sender, EventArgs e)
		{
			if (btnJustifyCenter.Checked)
				editor.Commands.JustifyCenter.Execute();
			else
				editor.Commands.JustifyNone.Execute();

			UpdateJustificationCommands();
		}

		private void btnJustifyLeft_Click(object sender, EventArgs e)
		{
			if (btnJustifyLeft.Checked)
				editor.Commands.JustifyLeft.Execute();
			else
				editor.Commands.JustifyNone.Execute();

			UpdateJustificationCommands();
		}

		private void btnToggleTagGlyphs_Click(object sender, EventArgs e)
		{
			editor.TagsVisible = !editor.TagsVisible;
		}

		private void viewSourceToolStripButton_Click(object sender, EventArgs e)
		{
			editor.ViewSource();
		}
		#endregion
	}
}
